package com.ruoyi.locksApi.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.locksApi.domain.WechatMiniProgramApiUser;
import com.ruoyi.locksApi.mapper.WechatMiniProgramApiMapper;
import com.ruoyi.locksApi.service.IWechatMiniProgramApiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.TimeUnit;

@Service
public class WechatMiniProgramApiServiceImpl implements IWechatMiniProgramApiService {

    @Value("${wx.miniapp.appid}")
    private String appid;

    @Value("${wx.miniapp.secret}")
    private String secret;

    @Autowired
    private WechatMiniProgramApiMapper wechatUserMapper;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public WechatMiniProgramApiUser getByOpenId(String openid) {
        return wechatUserMapper.selectByOpenId(openid);
    }

    @Override
    public WechatMiniProgramApiUser getByUnionId(String unionid) {
        return wechatUserMapper.selectByUnionId(unionid);
    }

    @Override
    public boolean save(WechatMiniProgramApiUser user) {
        return wechatUserMapper.insert(user) > 0;
    }

    @Override
    public boolean update(WechatMiniProgramApiUser user) {
        return wechatUserMapper.updateByOpenId(user) > 0;
    }

    @Override
    public boolean updatePhone(String openid, String phone) {
        return wechatUserMapper.updatePhone(openid, phone) > 0;
    }

    @Override
    @Transactional
    public WechatMiniProgramApiUser handleWechatLogin(String code, String encryptedData, String iv) {
        // 1. 通过code获取session_key和openid
        String url = String.format("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
                appid, secret, code);
        
        JSONObject response = restTemplate.getForObject(url, JSONObject.class);
        if (response == null || response.getString("openid") == null) {
            throw new RuntimeException("获取微信用户信息失败");
        }

        String openid = response.getString("openid");
        String sessionKey = response.getString("session_key");
        String unionid = response.getString("unionid");

        // 2. 查找或创建用户
        WechatMiniProgramApiUser user = getByOpenId(openid);
        if (user == null) {
            user = new WechatMiniProgramApiUser();
            user.setOpenid(openid);
            user.setUnionid(unionid);
            user.setRegisterTime(DateUtils.getNowDate());
            user.setStatus(1);
            save(user);
        }

        // 3. 更新登录时间
        user.setLastLoginTime(DateUtils.getNowDate());
        update(user);

        // 4. 缓存session_key，用于后续解密手机号
        String sessionKeyRedisKey = "wx:session_key:" + openid;
        redisCache.setCacheObject(sessionKeyRedisKey, sessionKey, 30, TimeUnit.MINUTES);

        return user;
    }

    @Override
    public boolean handlePhoneBinding(String openid, String code) {
        // 1. 通过code获取手机号
        String url = String.format("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=%s",
                getAccessToken());
        
        JSONObject params = new JSONObject();
        params.put("code", code);
        
        JSONObject response = restTemplate.postForObject(url, params, JSONObject.class);
        if (response == null || response.getJSONObject("phone_info") == null) {
            throw new RuntimeException("获取手机号失败");
        }

        String phoneNumber = response.getJSONObject("phone_info").getString("phoneNumber");
        if (StringUtils.isEmpty(phoneNumber)) {
            throw new RuntimeException("获取手机号失败");
        }

        // 2. 更新用户手机号
        return updatePhone(openid, phoneNumber);
    }

    /**
     * 获取小程序全局接口调用凭据
     */
    private String getAccessToken() {
        String accessTokenKey = "wx:access_token";
        String accessToken = redisCache.getCacheObject(accessTokenKey);
        if (StringUtils.isNotEmpty(accessToken)) {
            return accessToken;
        }

        String url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
                appid, secret);
        
        JSONObject response = restTemplate.getForObject(url, JSONObject.class);
        if (response == null || response.getString("access_token") == null) {
            throw new RuntimeException("获取access_token失败");
        }

        accessToken = response.getString("access_token");
        redisCache.setCacheObject(accessTokenKey, accessToken, 7000, TimeUnit.SECONDS);
        
        return accessToken;
    }
}
